The functools module is for higher-order functions: functions that act on or return other functions. In general, any callable object can be treated as a function for the purposes of this module.
Common functions in functools are as follows
In [47]:
def power(base, exponent):
return base ** exponent
In [48]:
def square(base):
return power(base, 2)
def cube(base):
return power(base, 3)
Now lets see the magic of partial
In [68]:
from functools import partial
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
print(square(2))
print(cube(2))
print(square(2, exponent=4))
print(cube(2, exponent=9))
In [73]:
from functools import partial
def multiply(x,y):
return x * y
# create a new function that multiplies by 2
db2 = partial(multiply,2)
print(db2(4))
db4 = partial(multiply, 4)
print(db4(3))
In [83]:
from functools import partial
#----------------------------------------------------------------------
def add(x, y):
""""""
return x + y
#----------------------------------------------------------------------
def multiply(x, y):
""""""
return x * y
#----------------------------------------------------------------------
def run(func):
""""""
print (func())
#----------------------------------------------------------------------
def main():
""""""
a1 = partial(add, 1, 2)
m1 = partial(multiply, 5, 8)
run(a1)
run(m1)
if __name__ == "__main__":
main()
In [101]:
def another_function(func):
"""
A function that accepts another function
"""
def wrapper():
"""
A wrapping function
"""
val = "The result of %s is %s" % (func(),
eval(func())
)
return val
return wrapper
#----------------------------------------------------------------------
@another_function
def a_function():
"""A pretty useless function"""
return "1+1"
#----------------------------------------------------------------------
if __name__ == "__main__":
print (a_function.__name__)
print (a_function.__doc__)
print(a_function())
In [81]:
from functools import wraps
#----------------------------------------------------------------------
def another_function(func):
"""
A function that accepts another function
"""
@wraps(func)
def wrapper():
"""
A wrapping function
"""
val = "The result of %s is %s" % (func(),
eval(func())
)
return val
return wrapper
#----------------------------------------------------------------------
@another_function
def a_function():
"""A pretty useless function"""
return "1+1"
#----------------------------------------------------------------------
if __name__ == "__main__":
#a_function()
print (a_function.__name__)
print (a_function.__doc__)
print(a_function())
Here we import wraps from the functools module and use it as a decorator for the nested wrapper function inside of another_function to map the name and doc to the wrapper function
In [1]:
import functools
def myfunc1(a, b=2):
print ('\tcalled myfunc1 with:', (a, b))
return
def myfunc(a, b=2):
"""Docstring for myfunc()."""
print ('\tcalled myfunc with:', (a, b))
return
def show_details(name, f):
"""Show details of a callable object."""
print ('%s:' % name)
print ('\tobject:', f)
print ('\t__name__:',)
try:
print (f.__name__)
except AttributeError:
print ('(no __name__)')
print ('\t__doc__', repr(f.__doc__))
print
return
show_details('myfunc1', myfunc1)
print("~"*20)
show_details('myfunc', myfunc)
p1 = functools.partial(myfunc, b=4)
print("+"*20)
show_details('raw wrapper', p1)
print("^"*20)
print ('Updating wrapper:')
print ('\tassign:', functools.WRAPPER_ASSIGNMENTS)
print ('\tupdate:', functools.WRAPPER_UPDATES)
print("*"*20)
functools.update_wrapper(p1, myfunc)
show_details('updated wrapper', p1)
In [ ]:
In [ ]: